/*
 * Copyright (c) 2023-2299 深圳市阿毛科技有限公司 All rights reserved.
 *
 * https://www.lamyz.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.lam.mall.api.service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

import javax.validation.constraints.NotNull;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.lam.common.constant.MallStateConstant;
import com.lam.common.utils.Arith;
import com.lam.common.utils.NumberUtil;
import com.lam.common.utils.StringUtils;
import com.lam.mall.app.vo.ProductItemVo;
import com.lam.mall.entity.Area;
import com.lam.mall.entity.ProdSku;
import com.lam.mall.entity.Product;
import com.lam.mall.entity.TransFeeItem;
import com.lam.mall.entity.TransFeeTemplate;
import com.lam.mall.entity.TransFree;
import com.lam.mall.entity.UserAddr;
import com.lam.mall.enums.TransFeeChargeType;
import com.lam.mall.service.ProdSkuService;
import com.lam.mall.service.ProductService;
import com.lam.mall.service.TransFeeTemplateService;

import cn.hutool.core.collection.CollectionUtil;
/**
 */
@Service
public class TransFeeManagerService {

    @Autowired
    private ProductService productService;
    @Autowired
    private ProdSkuService prodSkuService;
    @Autowired
    private TransFeeTemplateService transFeeTemplateService;

    public BigDecimal calcTransfee(ProductItemVo productItem, UserAddr userAddr) {
        Product product = productService.getSampleProdByIdCache(productItem.getProdId());
        if (!StringUtils.equals(product.getDeliveryMode(), MallStateConstant.DELIVERY_MODE_SHOP)) {
            return BigDecimal.ZERO;
        }
        
        if (product.getDeliveryTemplateId() == null) {
        	return BigDecimal.ZERO;
        }

        //找出该产品的运费项
        TransFeeTemplate transFeeTemplate = transFeeTemplateService.selectByIdCache(product.getDeliveryTemplateId());
        //商家把运费模板删除
        if (transFeeTemplate == null) {
            return BigDecimal.ZERO;
        }

        ProdSku sku = prodSkuService.getBySkuIdCache(productItem.getSkuId());

        // 用于计算运费的件数
        BigDecimal piece = getPiece(productItem, transFeeTemplate, sku);
        
        // 用户所在城市id
        String cityId = userAddr.getCityId();
        //如果有包邮的条件
        if (NumberUtil.eq(transFeeTemplate.getHasFreeCondition(), 1)) {
            // 获取所有的包邮条件
            List<TransFree> transFreeList = transFeeTemplate.getTransFreeList();
            for (TransFree transFree : transFreeList) {
                List<Area> freeCityList = transFree.getCityList();
                for (Area freeCity : freeCityList) {
                    if (!Objects.equals(freeCity.getId(), cityId)) {
                        continue;
                    }
                    //包邮方式 （0 满x件/重量/体积包邮 1满金额包邮 2满x件/重量/体积且满金额包邮）
                    if (isFreeTrans(transFree, productItem, piece)) {
                        return BigDecimal.ZERO;
                    }
                }
            }
        }

        //订单的运费项
        TransFeeItem transFeeItem = null;
        List<TransFeeItem> transFeeItemList = transFeeTemplate.getTransFeeItemList();
        for (TransFeeItem dbTransFeeItem : transFeeItemList) {
            // 将该商品的运费设置为默认运费
            if (transFeeItem == null && CollectionUtil.isEmpty(dbTransFeeItem.getCityList())) {
                transFeeItem = dbTransFeeItem;
            }
            // 如果在运费模板中的城市找到该商品的运费，则将该商品由默认运费设置为该城市的运费
            for (Area area : dbTransFeeItem.getCityList()) {
                if (area.getId().equals(cityId)) {
                    transFeeItem = dbTransFeeItem;
                    break;
                }
            }
            // 如果在运费模板中的城市找到该商品的运费，则退出整个循环
            if (transFeeItem != null && CollectionUtil.isNotEmpty(transFeeItem.getCityList())) {
                break;
            }
        }

        // 如果无法获取到任何运费相关信息，则返回0运费
        if (transFeeItem == null) {
            return BigDecimal.ZERO;
        }

        // 产品的运费
        BigDecimal fee = transFeeItem.getFirstFee();
        // 如果件数大于首件数量，则开始计算超出的运费
        if (NumberUtil.compare(piece, transFeeItem.getFirstPiece())>0) {
            // 续件数量
            BigDecimal prodContinuousPiece = NumberUtil.subtract(piece, transFeeItem.getFirstPiece());
            // 续件数量的倍数，向上取整
            Integer mulNumber = (int) Math.ceil(NumberUtil.divide(prodContinuousPiece, transFeeItem.getContinuousPiece()).doubleValue());
            // 续件数量运费
            BigDecimal continuousFee = NumberUtil.multiply(BigDecimal.valueOf(mulNumber), transFeeItem.getContinuousFee());
            fee = NumberUtil.add(fee, continuousFee);
        }
        return fee;
    }
    
    private boolean isFreeTrans(TransFree transFree, ProductItemVo productItem, BigDecimal piece) {
    	if(NumberUtil.eq(transFree.getFreeType(), MallStateConstant.FREE_TYPE_0) && NumberUtil.compare(piece, transFree.getPiece())>=0) {
    		return true;
    	}
    	if(NumberUtil.eq(transFree.getFreeType(), MallStateConstant.FREE_TYPE_1) && NumberUtil.compare(productItem.getProductTotalAmount(), transFree.getAmount())>=0) {
    		return true;
    	}
    	return NumberUtil.eq(transFree.getFreeType(), MallStateConstant.FREE_TYPE_2) && NumberUtil.compare(piece, transFree.getPiece()) >= 0 
    			&& NumberUtil.compare(productItem.getProductTotalAmount(), transFree.getAmount()) >= 0 ;
    }

    @NotNull
    private BigDecimal getPiece(ProductItemVo productItem, TransFeeTemplate transFeeTemplate, ProdSku sku) {
    	BigDecimal piece = BigDecimal.ZERO;

        if (Objects.equals(TransFeeChargeType.COUNT.value(), transFeeTemplate.getChargeType())) {
            // 按件数计算运费
            piece = BigDecimal.valueOf(productItem.getProdCount());
        } else if (Objects.equals(TransFeeChargeType.WEIGHT.value(), transFeeTemplate.getChargeType())) {
            // 按重量计算运费
            double weight = sku.getWeight() == null ? 0 : sku.getWeight();
            piece = BigDecimal.valueOf(Arith.mul(weight, productItem.getProdCount()));
        } else if (Objects.equals(TransFeeChargeType.VOLUME.value(), transFeeTemplate.getChargeType())) {
            // 按体积计算运费
            double volume = sku.getVolume() == null ? 0 : sku.getVolume();
            piece = BigDecimal.valueOf(Arith.mul(volume, productItem.getProdCount()));
        }
        return piece;
    }


}
